<?php

namespace support;

use Predis\Client;
use Psr\SimpleCache\CacheInterface;
use Workerman\Timer;
use Workerman\Worker;
use Yiisoft\Cache\Redis\RedisCache;
use Yiisoft\Db\Cache\SchemaCache;
use Yiisoft\Db\Mysql\Connection;
use Yiisoft\Db\Mysql\Driver;
use Yiisoft\Db\Mysql\Dsn;
use Yiisoft\Factory\Factory;

class YiiOrm implements \Webman\Bootstrap
{

    /**
     * @inheritDoc
     */
    public static function start(?Worker $worker)
    {
        // TODO: Implement start() method.
        /** @var \Webman\Container $container */
        $container = config('container');
        $container->addDefinitions(['yiiRedis' => ['\support\YiiOrm', 'getRedis']]);
        $container->addDefinitions(['yiiCache' => ['\support\YiiOrm', 'getRedisCache']]);
        $container->addDefinitions(['yiiDbs' => ['\support\YiiOrm', 'getDbs']]);
//
//        // -----功能测试-----
//        /** @var Client $redis */
//        $redis = $container->get('yiiRedis');
//        $redis->set('test', time());
//        /** @var RedisCache $cache */
//        $cache = $container->get('yiiCache');
//        $cache->set('99999999', time());
//
//        $dbs = $container->get('yiiDbs');
//        /** @var Connection $db */
//        $db = $dbs['default'];
//        $res = (new Query($db))->from('yjh_users')->where(['id' => 1])->one();
//        print_r($res);
//

        if ($worker) {
            Timer::add(55, function () use ($container, $worker) {
                /** @var Client $redis */
                $redis = $container->get('yiiRedis');
                $redis->ping();
                Log::info($worker->name.' redis ping' . $redis->set('aa', time()));

                $dbs = $container->get('yiiDbs');
                foreach ($dbs as $key => $connection) {
                    /* @var Connection $connection */
                    Log::info($worker->name.' db ping-' . $key);
                    try {
                        $connection->createCommand('select 1')->queryOne();
                    } catch (\Exception $e) {
                    }
                }
            });
        }
    }

    /**
     * @return array
     * @throws \Yiisoft\Definitions\Exception\CircularReferenceException
     * @throws \Yiisoft\Definitions\Exception\InvalidConfigException
     * @throws \Yiisoft\Definitions\Exception\NotInstantiableException
     * @throws \Yiisoft\Factory\NotFoundException
     * @author: luwc
     * @time: 2024/5/23 16:14:23
     */
    public static function getDbs(\Webman\Container $container)
    {
        // 读取配置
        $configs = config('yiiorm');
        $factory = new Factory();
        $dbConnects = [];
        foreach ($configs['connections'] as $key => $config) {
            $dsn = new Dsn($config['driver'], $config['host'], $config['database'], $config['hostport'], ['charset' => $config['charset']]);
            $dbConnects[$key] = $factory->create([
                'class' => \Yiisoft\Db\Mysql\Connection::class,
                '__construct()' => [
                    'driver' => new Driver($dsn, $config['username'], $config['password']),
                    'schemaCache' => self::getSchemaCache()
                ],
            ]);
        }
        return $dbConnects;
    }

    /**
     * @return \int[][][]|mixed|object|Client[]|\string[][][]
     * @throws \Yiisoft\Definitions\Exception\CircularReferenceException
     * @throws \Yiisoft\Definitions\Exception\InvalidConfigException
     * @throws \Yiisoft\Definitions\Exception\NotInstantiableException
     * @throws \Yiisoft\Factory\NotFoundException
     * @author: luwc
     * @time: 2024/5/23 15:52:16
     */
    public static function getRedis(\Webman\Container $container)
    {
        // 读取配置
        $config = config('redis');
        $factory = new Factory();
        return $factory->create([
            'class' => Client::class,
            '__construct()' => [
                'parameters' => [
                    'host' => $config['cache']['host'],
                    'port' => $config['cache']['port'],
                    'database' => $config['cache']['database'],
                    'password' => $config['cache']['password'],
                ],
            ],
        ]);
    }

    /**
     * @return \#C\Predis\Client[][]|mixed|object|RedisCache[]
     * @throws \Yiisoft\Definitions\Exception\CircularReferenceException
     * @throws \Yiisoft\Definitions\Exception\InvalidConfigException
     * @throws \Yiisoft\Definitions\Exception\NotInstantiableException
     * @throws \Yiisoft\Factory\NotFoundException
     * @author: luwc
     * @time: 2024/5/23 16:02:45
     */
    public static function getRedisCache(\Webman\Container $container)
    {
        $container = config('container');
        /** @var Client $redis */
        $redis = $container->get('yiiRedis');
        $factory = new Factory();
        return $factory->create([
            'class' => RedisCache::class,
            '__construct()' => [
                'client' => $redis,
            ],
        ]);
    }

    /**
     * @return CacheInterface
     * @author: luwc
     * @time: 2024/5/23 16:07:17
     */
    public static function getPsrCache(): CacheInterface
    {
        $container = config('container');
        /** @var RedisCache $redis */
        $cache = $container->get('yiiCache');
        return $cache;
    }

    public static function getSchemaCache(): SchemaCache
    {
        return new SchemaCache(self::getPsrCache());
    }
}